package pers.whj.util.list;

import pers.whj.util.NoSuchElementException;

/**
 * implements interface Stack, use array to store the data, and has fixed length
 *
 * @param <T> the type of data
 */
public class StackImpl<T> implements Stack<T> {
    protected Object[] mData;
    protected int mLength;
    protected int mMaxLength;

    public StackImpl(int maxLength) {
        mMaxLength = Math.max(maxLength, 0);
        mData = new Object[mMaxLength];
        mLength = 0;
    }

    @Override
    public int length() {
        return mLength;
    }

    @Override
    public int maxLength() {
        return mMaxLength;
    }

    @Override
    public boolean push(T data) {
        checkForAdd();
        mData[mLength++] = data;
        return true;
    }

    @Override
    public T pop() {
        checkForRemove();
        return data(--mLength);
    }

    @Override
    public T peek() {
        checkForRemove();
        return data(mLength - 1);
    }

    @Override
    public boolean isEmpty() {
        return mLength == 0;
    }

    @Override
    public boolean isFull() {
        return mLength == mMaxLength;
    }

    @SuppressWarnings("unchecked")
    protected T data(int index) {
        return (T) mData[index];
    }

    protected void checkForAdd() {
        if (mLength == mMaxLength) {
            throw new IllegalStateException("stack is full, current length: " + length());
        }
    }

    protected void checkForRemove() {
        if (mLength == 0) {
            throw new NoSuchElementException("stack is empty");
        }
    }
}